package com.deer.wms.inventory.service.impl;

//import com.deer.wms.base.system.model.TaskLog;
//import com.deer.wms.base.system.model.container.ContItem;
//import com.deer.wms.base.system.model.container.ContItemDto;
//import com.deer.wms.base.system.service.ContItemService;
//import com.deer.wms.base.system.service.TaskLogService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.deer.wms.base.system.dao.ErpBackRecordMapper;
import com.deer.wms.base.system.model.ErpBackRecord;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.inventory.dao.StockTakeLogMapper;
import com.deer.wms.inventory.model.InventoryDto;
import com.deer.wms.inventory.model.Lines;
import com.deer.wms.inventory.model.stockTake.*;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.inventory.service.StockTakeLogService;
import com.deer.wms.inventory.service.StockTakeMasterService;
import com.deer.wms.inventory.service.StockTakeTaskService;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.service.SuperServiceImpl;
import com.deer.wms.project.root.util.DateUtils;
import com.deer.wms.project.root.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by csl on 2021/04/13.
 */
@Service
@Transactional
public class StockTakeLogServiceImpl extends SuperServiceImpl<StockTakeLogMapper, StockTakeLog> implements StockTakeLogService {

    @Autowired
    private StockTakeLogMapper stockTakeLogMapper;

    @Autowired
    private StockTakeTaskService stockTakeTaskService;

    @Autowired
    private StockTakeMasterService stockTakeMasterService;

    @Autowired
    private InventoryService inventoryService;
    
    @Autowired
    private StockTakeLogService stockTakeLogService;

//    @Autowired
//    private TaskLogService taskLogService;

//    @Autowired
//    private ContItemService contItemService;

    /**
     * 保存盘点记录
     * @param stockTakeLogDto
     * @param currentUser
     */
    @Override
    public void saveLog(StockTakeLogDto stockTakeLogDto, CurrentUser currentUser) {
        if (stockTakeLogDto.getItemList() != null){
            List<Map<String,Object>> itemList = stockTakeLogDto.getItemList();
            if (itemList.size()>0){
                for (Map<String,Object> item : itemList){
                    StockTakeLog stockTakeLog = new StockTakeLog();
                    stockTakeLog.setStockMasterId(stockTakeLogDto.getStockTakeMasterId());
                    stockTakeLog.setStockMasterCode(stockTakeLogDto.getStockMasterCode());
                    stockTakeLog.setStockTaskId(stockTakeLogDto.getStockTaskId());
                    stockTakeLog.setStockTaskCode(stockTakeLogDto.getTaskBillNo());
                    stockTakeLog.setCellCode(stockTakeLogDto.getCellCode());
                    stockTakeLog.setContCode(stockTakeLogDto.getBoxCode());
                    stockTakeLog.setWareId(stockTakeLogDto.getWareId());
                    stockTakeLog.setTaskUserId(currentUser.getUserId());
                    stockTakeLog.setTaskUserName(currentUser.getUserName());
                    stockTakeLog.setTaskTime(DateUtils.getNowDateTimeString());
                    stockTakeLog.setItemCode(String.valueOf(item.get("itemCode")));
                    stockTakeLog.setItemName(String.valueOf(item.get("itemName")));
                    if (item.get("itemPc")!=null){
                        stockTakeLog.setItemPc(String.valueOf(item.get("itemPc")));
                    }
                    stockTakeLog.setQuantity(Double.parseDouble(String.valueOf(item.get("quantity"))));
                    stockTakeLog.setTaskQuantity(Double.parseDouble(String.valueOf(item.get("taskQuantity"))));
                    Double residualQuantity = Double.parseDouble(String.valueOf(item.get("taskQuantity"))) - Double.parseDouble(String.valueOf(item.get("quantity")));
                    if (residualQuantity>0){
                        stockTakeLog.setProfitOrLoss(1);
                    }else if (residualQuantity<0){
                        stockTakeLog.setProfitOrLoss(-1);
                    }else {
                        stockTakeLog.setProfitOrLoss(0);
                    }
                    stockTakeLog.setResidualQuantity(residualQuantity);
                    stockTakeLogService.save(stockTakeLog);
                }
                //保存成功之后修改盘点状态
//                StockTakeTask stockTakeTask = new StockTakeTask();
                StockTakeTask stockTakeTask = stockTakeTaskService.getById(stockTakeLogDto.getStockTaskId());

//                stockTakeTask.setStockTakeTaskId(stockTakeLogDto.getStockTaskId());
//                stockTakeTask.setStockTakeMasterId(stockTakeLogDto.getStockTakeMasterId());
//                stockTakeTask.setTaskBillNo(stockTakeLogDto.getTaskBillNo());
//                stockTakeTask.setCellCode(stockTakeLogDto.getCellCode());
                stockTakeTask.setBoxCode(stockTakeLogDto.getBoxCode());
                stockTakeTask.setTaskTime(DateUtils.getNowDateTimeString());
                stockTakeTask.setTaskUserName(currentUser.getUserName());
                stockTakeTask.setState(2);
                stockTakeTaskService.updateById(stockTakeTask);
                //查询该盘点任务号下所有下架任务是否都完成
                Integer num = stockTakeTaskService.selectNum(stockTakeLogDto.getStockTakeMasterId());
                if (num == 0){//表示全部完成，修改盘点任务状态为已完成
//                    StockTakeMaster stockTakeMaster = new StockTakeMaster();
                    StockTakeMaster stockTakeMaster = stockTakeMasterService.getById(stockTakeLogDto.getStockTakeMasterId());
//                    stockTakeMaster.setStockTakeMasterId(stockTakeLogDto.getStockTakeMasterId());
                    stockTakeMaster.setState(1);
                    stockTakeMasterService.updateById(stockTakeMaster);
                }
            }
        }
        else {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR,"数据错误");
        }

    }

      //数据库中有，实际库存没有  盘亏
//    private void setLog(StockTakeLogDto stockTakeLogDto,CurrentUser currentUser,ContItemDto contItemDto){
//        StockTakeLog stockTakeLog = new StockTakeLog();
//        stockTakeLog.setStockMasterId(stockTakeLogDto.getStockMasterId());
//        stockTakeLog.setStockMasterCode(stockTakeLogDto.getStockMasterCode());
//        stockTakeLog.setStockTaskId(stockTakeLogDto.getStockTaskId());
//        stockTakeLog.setStockTaskCode(stockTakeLogDto.getStockTaskCode());
//        stockTakeLog.setCellCode(stockTakeLogDto.getCellCode());
//        stockTakeLog.setContCode(stockTakeLogDto.getContCode());
//        stockTakeLog.setWareId(stockTakeLogDto.getWareId());
//        stockTakeLog.setTaskUserId(currentUser.getUserId());
//        stockTakeLog.setTaskUserName(currentUser.getUserName());
//        stockTakeLog.setTaskTime(DateUtils.getNowDateTimeString());
//        stockTakeLog.setContItemId(contItemDto.getId());
//        stockTakeLog.setItemCode(contItemDto.getItemInfo().getItemCode());
//        stockTakeLog.setItemName(contItemDto.getItemInfo().getItemName());
//        if (contItemDto.getBatchNumber() != null){
//            stockTakeLog.setItemPc(contItemDto.getBatchNumber());
//        }
//        if (contItemDto.getBuildNumber() != null){
//            stockTakeLog.setBuildNumber(contItemDto.getBuildNumber());
//        }
//        stockTakeLog.setQuantity(contItemDto.getQty());
//        stockTakeLog.setTaskQuantity(0.0);
//        stockTakeLog.setProfitOrLoss(-1);
//        stockTakeLog.setResidualQuantity(0.0-contItemDto.getQty());
//        save(stockTakeLog);
//    }
    
    
    /**
     * 根据盘点下架任务号查询盘点记录
     * @param wareId
     * @param stockTaskCode
     * @return
     */
    @Override
    public List<StockTakeLog> findList(Integer wareId, String stockTaskCode) {
        return stockTakeLogMapper.findList(wareId,stockTaskCode);
    }

    /**
     * 根据盘点任务号查询盘点差异表
     * @param wareId
     * @param stockMasterCode
     * @return
     */
    @Override
    public List<StockTakeLog> findResidualList(Integer wareId, String stockMasterCode) {
        return stockTakeLogMapper.findResidualList(wareId,stockMasterCode);
    }

    /**
     * 盘点单回传
     */
    @Override
    public Object inventoryReturn(Integer wareId, String stockMasterCode) {
        //获取盘点记录
        List<StockTakeLog> stockTakeLogList = stockTakeLogMapper.inventoryReturnLog(wareId,stockMasterCode);
        if (stockTakeLogList.size() == 0){
            return stockTakeLogList;
        }
        if (stockTakeLogList.size() > 0){
            stockTakeLogList = stockTakeLogList.stream().filter(t->t.getTotal() != 0).collect(Collectors.toList());
        }
        List<InventoryDto> inventoryDtos = new ArrayList<>();
        InventoryDto inventoryDto = new InventoryDto();
        StockTakeLog stockTakeLog = stockTakeLogList.get(0);
        inventoryDto.setDocNo(stockTakeLog.getStockMasterCode());//盘点单据号
        LambdaQueryWrapper<StockTakeMaster> masterQuery = new LambdaQueryWrapper<>();
        masterQuery.eq(StockTakeMaster::getBillNo,stockTakeLog.getStockMasterCode());
        StockTakeMaster one = stockTakeMasterService.getOne(masterQuery);
        if (StringUtils.isNotEmpty(one.getUdfHs2())){
            if (one.getUdfHs2().equals("1")){
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR,"盘点单已经被推送过,请勿重复推送");
            }
        }
        inventoryDto.setWhCode(one.getUdfHs1());//存储地点编码
        List<Lines> linesList = new ArrayList<>();
        stockTakeLogList.stream().forEach(t->{
            Lines lines = new Lines();
            lines.setItemCode(t.getItemCode());//料品编码
            lines.setInvQty(t.getTaskQuantity());//实盘数量
            //查询库存
            lines.setLotCode(t.getItemPc());//批次
            linesList.add(lines);
        });
        inventoryDto.setLines(linesList);
        inventoryDtos.add(inventoryDto);
        Map<String, Object> returnMap = doPostOrGet("http://61.160.125.186:5555/zp/api/ZpViewInv/Create",JSONObject.toJSONString(inventoryDtos));
        if (returnMap.get("code")!= null && "200".equals(returnMap.get("code").toString())){
            one.setUdfHs2("1");
            stockTakeMasterService.updateById(one);
            erpLog(returnMap,2007);
        }else {
            erpLog(returnMap,2007);
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR,returnMap.get("msg").toString());
        }
        return returnMap;
    }

    @Autowired
    private ErpBackRecordMapper erpBackRecordMapper;

    /**
     * 添加回传日志信息
     * @param returnMap
     */
    public void erpLog(Map<String,Object> returnMap,int type){
        //添加回传日志信息
        ErpBackRecord erpBackRecord = new ErpBackRecord();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String tim = df.format(new Date());
        erpBackRecord.setCreateTime(tim);
        erpBackRecord.setParam(returnMap.get("result").toString());
        erpBackRecord.setMsg(returnMap.get("msg").toString());
        erpBackRecord.setCode(returnMap.get("code").toString());
        erpBackRecord.setType(type+"");
        erpBackRecordMapper.insert(erpBackRecord);
    }

    /**
     * 根据盘点任务号查询盘点盈亏记录
     * @param wareId
     * @param stockMasterCode
     * @param profitOrLoss
     * @return
     */
    @Override
    public List<StockTakeLog> findProfitOrLossList(Integer wareId, String stockMasterCode, Integer profitOrLoss) {
        return stockTakeLogMapper.findProfitOrLossList(wareId,stockMasterCode,profitOrLoss);
    }

    /**
     * 调用第三方接口
     * @param pathUrl 地址
     * @param data    参数
     * @return
     */
    public static Map<String,Object> doPostOrGet(String pathUrl, String data){
        System.out.println("=========================================================");
        System.out.println(data);
        System.out.println("=========================================================");
        OutputStreamWriter out = null;
        BufferedReader br = null;
        String result = "";
        Map<String, Object> map = new HashMap<>();
        try {
            URL url = new URL(pathUrl);
            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //请求方式
            conn.setRequestMethod("POST");
            //conn.setRequestMethod("GET");

            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");

            //DoOutput设置是否向httpUrlConnection输出，DoInput设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            conn.setDoOutput(true);
            conn.setDoInput(true);

            /**
             * 下面的三句代码，就是调用第三方http接口
             */
            //获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            //发送请求参数即数据
            out.write(data);
            //flush输出流的缓冲
            out.flush();

            /**
             * 下面的代码相当于，获取调用第三方http接口后返回的结果
             */
            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str = br.readLine()) != null){
                result += str;
            }
            map = JSON.parseObject(result);
            System.out.println(result);
            //关闭流
            is.close();
            //断开连接，disconnect是在底层tcp socket链接空闲时才切断，如果正在被其他线程使用就不切断。
            conn.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (out != null){
                    out.close();
                }
                if (br != null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }




}
